Skip to content

如何將 Vue 與 ASP.NET Razor 一起使用

TLDR

  • 架構整合:透過 _Layout.cshtml 統一初始化 Vue 實例,並利用 mixins 將各頁面的邏輯注入,實現模組化管理。
  • 解決閃現:使用 v-cloak 配合 CSS [v-cloak] { display: none; } 解決頁面載入時的模板閃現問題。
  • 避免衝突:Vue 模板內禁止使用 <script> 標籤;Razor 語法與 Vue 語法(如 @)衝突時,需使用 @@ 進行跳脫。
  • Ajax 安全性:使用 axios 攔截器(Interceptor)自動將 RequestVerificationToken 加入 Header,以符合 ASP.NET Core 的防偽要求。
  • 驗證機制:透過自定義 Tag Helper 將 C# Model Validation 屬性轉換為 VeeValidate 規則,保留後端驗證的同時實現前端即時回饋。

架構整合:Vue 與 Razor 的協作

在 ASP.NET Razor Pages 中整合 Vue,建議將 Vue 實例的初始化邏輯集中於 _Layout.cshtml,並利用 mixins 機制將各頁面的資料與方法注入。

核心實作方式

  1. 根結點設定:在 _Layout.cshtml 定義一個包含 v-cloak 的容器,確保 Vue 編譯完成前隱藏內容。
  2. Mixin 注入:在 _Layout.cshtml 宣告全域 mixins 陣列,各頁面透過 @section Scripts 將該頁面的邏輯 push 進陣列。
  3. 初始化:最後在 _Layout.cshtml 底部統一 new Vue({ el: '#vueApp', mixins: mixins })

常見開發注意事項

1. 避免模板編譯錯誤

什麼情況下會遇到:在 Vue 的掛載範圍內直接撰寫 <script> 標籤。

  • 原因:Vue 模板僅負責 UI 映射,不允許包含具副作用的標籤。
  • 建議:所有 JavaScript 邏輯應移至 @section Scripts 區塊中。

2. Razor 與 Vue 語法衝突

什麼情況下會遇到:在 Razor 頁面中使用 Vue 的 @ 簡寫語法(如 @click)。

  • 原因@ 是 Razor 的關鍵字,會導致編譯錯誤。
  • 建議:使用 @@ 進行跳脫(例如 @@click)。若在 Tag Helper 中使用,則需確保 @ 僅出現在屬性值內,否則會導致 Tag Helper 解析失敗。

取代 jQuery 的替代方案

Ajax 請求與 XSRF 防護

由於 ASP.NET Core Razor Pages 會自動執行防偽驗證,使用 axios 時需確保 Header 帶有正確的 Token。

javascript
axios.interceptors.request.use(
    config => {
        let token = document.querySelector('input[name="__RequestVerificationToken"]');
        if (token !== null) {
            config.headers = {
                RequestVerificationToken: token.value
            }
        }
        return config;
    },
    error => Promise.reject(error)
);

前端驗證:整合 VeeValidate 與 Model Validation

什麼情況下會遇到:希望在不棄用 ASP.NET 原生 [Required][EmailAddress] 等驗證屬性的前提下,實現前端即時驗證。

  • 解決方案:編寫自定義 TagHelper,將 C# 的 ModelMetadata 轉換為 VeeValidate 的 HTML 屬性(如 v-validate)。
  • 驗證結果
    • 透過 VeeValidationInputTagHelper 自動產生驗證規則。
    • 透過 VeeValidationMessageTagHelper 綁定 v-show 與錯誤訊息顯示。
    • 在 Vue 的 created 鉤子中,將後端 ModelState 的錯誤訊息注入 this.$validator.errors,確保後端驗證失敗時前端能同步顯示錯誤。

異動歷程

    • 初版文件建立。